import Vue from "vue";

export interface EventBusOperation<State = any> {
  $on: (
    //监听
    event: string,
    callback: (context: BaseEventBus<State>) => void
  ) => EventBusOperation;
  $off: (
    //取消监听
    event: string,
    callback: Function
  ) => EventBusOperation;
  $once: (
    //只监听一次
    event: string,
    callback: (context: BaseEventBus<State>) => void
  ) => EventBusOperation;
  $emit: (event: string, ...args: any[]) => EventBusOperation; //发送事件
  $clear: Function; //清除监听
}

export class BaseEventBus<State = any> {
  public prefix?: string; //event前缀
  public operation: EventBusOperation<State>; //操作栏
  public state?: Partial<State>; //数据
  public events: {
    //当前属于该总线监听事件数组
    event: string;
    func: Function;
  }[] = [];
  constructor() {
    const vue = new Vue();
    const context = this;
    this.operation = {
      $on: (event, callback) => {
        const nevent = `${this.prefix ? this.prefix + "-" : ""}${event}`;
        vue.$on(nevent, () => callback(context));
        this.events.push({
          event: nevent,
          func: callback
        });
        return context.operation;
      },
      $off: (event, callback) => {
        const nevent = `${this.prefix ? this.prefix + "-" : ""}${event}`;
        vue.$off(nevent, callback);
        const result = this.events.findIndex(item => item.event === event);
        if (result !== -1) this.events.splice(result, 1);
        return context.operation;
      },
      $once: (event, callback) => {
        vue.$once(`${this.prefix ? this.prefix + "-" : ""}${event}`, () =>
          callback(context)
        );
        return context.operation;
      },
      $emit: (event, ...args: any[]) => {
        vue.$emit(`${this.prefix ? this.prefix + "-" : ""}${event}`, args);
        return context.operation;
      },
      $clear: () => {
        this.events.forEach(item => {
          vue.$off(item.event, item.func);
        });
      }
    };
  }
}
